﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;
using LowLevelGraphics;
using LowLevelGraphics.Filter;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// Stere from Still and Depthmap
    /// This is a pic and a depthmap in combination to create a 3d image
    /// </summary>
    public class StereoFromStillAndDepthmap : BaseImageFilter, ITwoSourceFilter
    {
        private static bool b_Smoothing = true;
        private static int i_maxDisplacement = 12;
        private static Bitmap b_Anaglyph = null;
        private static bool b_SwapRL = false;
        private static bool b_InverseDepthMap = false;
        private static Bitmap b_CH2 = null;
        private static Bitmap b_CH1  = null;
        private static bool m_bCreateAnaglyph = true;

        private Bitmap m_BitmapStill = null;
        private Bitmap m_BitmapDepthMap = null;

        /// <summary>
        /// Constructor
        /// </summary>
        public StereoFromStillAndDepthmap()
        {
        }

        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="_bitmapStill"></param>
        /// <param name="_bitmapDepth"></param>
        /// <param name="_bCreateAnaglyph"></param>
        public StereoFromStillAndDepthmap(Bitmap _bitmapStill, Bitmap _bitmapDepth, bool _bCreateAnaglyph)
        {
            m_bCreateAnaglyph = _bCreateAnaglyph;
            m_BitmapStill = _bitmapStill;
            m_BitmapDepthMap = _bitmapDepth;
        }

        internal StereoFromStillAndDepthmap(StereoFromStillAndDepthmap _stereoFromStillAndDepthmap)
        {

        }

        /// <summary>
        /// gets or sets create anaglyph mode
        /// </summary>
        public bool CreateAnaglyph
        {
            get { return m_bCreateAnaglyph; }
            set { m_bCreateAnaglyph = value; }
        }

        /// <summary>
        /// Execute this filter
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            if (m_bCreateAnaglyph)
            {
                GenerateAnaglyph(m_BitmapStill, m_BitmapDepthMap);
            }
            else
            {
                GenerateStereoscopic(m_BitmapStill, m_BitmapDepthMap);
            }
            return b_Anaglyph;
        }

        /// <summary>
        /// Generate Anaglyph Map
        /// </summary>
        /// <param name="Image"></param>
        /// <param name="DepthMap"></param>
        /// <returns></returns>
        public unsafe static bool GenerateAnaglyph(Bitmap Image, Bitmap DepthMap)
        {
            //' Checking if image and depthmap have same size
            if (Image.Width != DepthMap.Width || Image.Height != DepthMap.Height)
                throw new ArgumentException("Size of Image and DepthMap are not same.");
            //' Check if image and depthmap are 24bitRGB or not
            if (Image.PixelFormat != PixelFormat.Format24bppRgb || Image.PixelFormat != PixelFormat.Format24bppRgb)
                throw new ArgumentException("Image and/or DepthMap are/is not 24bitRGB");
            try
            {
                //' Locking image and depthmap so other threads cant access them when we work
                lock (Image)
                {
                    lock (DepthMap)
                    {
                        //' Create a clean bitmap for saving output
                        b_Anaglyph = new Bitmap(DepthMap.Width, Image.Height);
                        //' Create a rect object, Same size as bitmap. Need for direct access in memory
                        Rectangle r_Anaglyph = new Rectangle(0, 0, DepthMap.Width, Image.Height);
                        //' Calculating real width of image (By byte)
                        int i_width = DepthMap.Width * 3;
                        if (i_width % 4 != 0)
                        {
                            i_width = 4 * (i_width / 4 + 1);
                        }

                        //' How much we need to move each pixel per depth byte
                        double hsrate = i_maxDisplacement / 255;

                        //' Creating a rect object with same size. For Depth map
                        Rectangle r_depth = new Rectangle(0, 0, DepthMap.Width, DepthMap.Height);
                        //' Opening direct access to bitmap data in memory for Depth map
                        BitmapData d_depth = DepthMap.LockBits(r_depth, ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

                        //' Creating a rect object with same size. For Image
                        Rectangle r_image = new Rectangle(0, 0, Image.Width, Image.Height);
                        //' Opening direct access to bitmap data in memory for Image
                        BitmapData d_image = Image.LockBits(r_image, ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

                        //' Opening direct access to bitmap data in memory for Output Bitmap
                        BitmapData d_anag = b_Anaglyph.LockBits(r_Anaglyph, ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

                        int sfp = 0;

                        for (int y = 0; y <= DepthMap.Height - 1; y++)
                        {
                            //' Calculate location of current line's last free pixel
                            IntPtr rLPDest = (IntPtr)((y + 1) * i_width - (i_maxDisplacement * 3) - 3);

                            //' Calculate location of current line's first free pixel
                            IntPtr rFPDest = (IntPtr)(y * i_width + (i_maxDisplacement * 3));

                            //' Count for each pixel on width of image. Cut MaxDisplacementfrom both sides

                            for (int x = i_maxDisplacement; x <= DepthMap.Width - 1 - i_maxDisplacement; x++)
                            {
                                ///''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Right 2 Left  <<--
                                //' Read Depth, Right to Left
                                byte depthrgb = Marshal.ReadByte((IntPtr)((int)d_depth.Scan0 + (int)rLPDest + 1));
                                if (InverseDepthMap)
                                    depthrgb = (byte)(255 - depthrgb);

                                //' Calculate displacement offset, Right to Left
                                sfp = (int)(depthrgb * hsrate);

                                //' Read BYTE from Image And Displace, Right to Left
                                if ((!b_SwapRL))
                                {
                                    //' RED
                                    Marshal.WriteByte((IntPtr)((int)d_anag.Scan0 + (int)rLPDest + ((sfp) * 3) + 2), Marshal.ReadByte((IntPtr)((int)d_image.Scan0 + (int)rLPDest + 2)));
                                }
                                else
                                {
                                    //' BLUE
                                    Marshal.WriteByte((IntPtr)((int)d_anag.Scan0 + (int)rLPDest + ((sfp) * 3)), Marshal.ReadByte((IntPtr)((int)d_image.Scan0 + (int)rLPDest)));
                                    //' Read GREEM And Displace it just like BLUE
                                    Marshal.WriteByte((IntPtr)((int)d_anag.Scan0 + (int)rLPDest + ((sfp) * 3) + 1), Marshal.ReadByte((IntPtr)((int)d_image.Scan0 + (int)rLPDest + 1)));
                                }


                                //' Smoothing
                                if (b_Smoothing & sfp != 0)
                                {
                                    //' Calculate color changes between pixels (For better smoothing we use 4 pixel and then get an average)
                                    double ich1Rgrate = 0;
                                    double ich1Bgrate = 0;
                                    double ich1Ggrate = 0;
                                    byte[] db = new byte[12];
                                    Marshal.Copy((IntPtr)((int)d_image.Scan0 + (int)rLPDest - 12), db, 0, 12);
                                    db[11] = Convert.ToByte((Convert.ToInt32(db[11]) + Convert.ToInt32(db[8])) / 2);
                                    db[10] = Convert.ToByte((Convert.ToInt32(db[10]) + Convert.ToInt32(db[7])) / 2);
                                    db[9] = Convert.ToByte((Convert.ToInt32(db[9]) + Convert.ToInt32(db[6])) / 2);
                                    db[2] = Convert.ToByte((Convert.ToInt32(db[2]) + Convert.ToInt32(db[5])) / 2);
                                    db[1] = Convert.ToByte((Convert.ToInt32(db[1]) + Convert.ToInt32(db[4])) / 2);
                                    db[0] = Convert.ToByte((Convert.ToInt32(db[0]) + Convert.ToInt32(db[3])) / 2);

                                    //' Split color changes between pixels that we need to write. So we can create a gradient effect
                                    ich1Rgrate = (Convert.ToInt32(db[2]) - Convert.ToInt32(db[11])) / (sfp + 1);
                                    ich1Ggrate = (Convert.ToInt32(db[1]) - Convert.ToInt32(db[10])) / (sfp + 1);
                                    ich1Bgrate = (Convert.ToInt32(db[0]) - Convert.ToInt32(db[9])) / (sfp + 1);

                                    //' Apply Smoothing
                                    for (int i = 0; i <= sfp - 1; i++)
                                    {
                                        //' CH1 Smoothing
                                        if ((!b_SwapRL))
                                        {
                                            //' RED
                                            Marshal.WriteByte((IntPtr)((int)d_anag.Scan0 + (int)rLPDest + (((sfp - 1) - i) * 3) + 2), (byte)(db[11] + (i * ich1Rgrate)));
                                        }
                                        else
                                        {
                                            //' BLUE
                                            Marshal.WriteByte((IntPtr)((int)d_anag.Scan0 + (int)rLPDest + (((sfp - 1) - i) * 3)), (byte)(db[9] + (i * ich1Bgrate)));
                                            Marshal.WriteByte((IntPtr)((int)d_anag.Scan0 + (int)rLPDest + (((sfp - 1) - i) * 3) + 1), (byte)(db[10] + (i * ich1Ggrate)));
                                        }
                                    }
                                }
                                //' Go to last pixel
                                rLPDest -= 3;

                                ///''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Left 2 Right  -->>
                                //' Read Depth, Left to Right
                                depthrgb = Marshal.ReadByte((IntPtr)((int)d_depth.Scan0 + (int)rFPDest + 1));
                                if (InverseDepthMap)
                                    depthrgb = (byte)(255 - depthrgb);

                                //' Calculate displacement offset, Left to Right
                                sfp = (int)(depthrgb * hsrate);

                                //' Read BYTE from Image And Displacment, Left to Right
                                if ((!b_SwapRL))
                                {
                                    //' BLUE
                                    Marshal.WriteByte((IntPtr)((int)d_anag.Scan0 + (int)rFPDest + (-sfp * 3)), Marshal.ReadByte((IntPtr)((int)d_image.Scan0 + (int)rFPDest)));
                                    //' Read GREEM And Displace it just like BLUE
                                    Marshal.WriteByte((IntPtr)((int)d_anag.Scan0 + (int)rFPDest + (-sfp * 3) + 1), Marshal.ReadByte((IntPtr)((int)d_image.Scan0 + (int)rFPDest + 1)));
                                }
                                else
                                {
                                    //' RED
                                    Marshal.WriteByte((IntPtr)((int)d_anag.Scan0 + (int)rFPDest + (-sfp * 3) + 2), Marshal.ReadByte((IntPtr)((int)d_image.Scan0 + (int)rFPDest + 2)));
                                }

                                //' Smoothing
                                if (b_Smoothing & sfp != 0)
                                {
                                    //' Calculate color changes between pixels (For better smoothing we use 4 pixel and then get an average)
                                    double ich2Rgrate = 0;
                                    double ich2Bgrate = 0;
                                    double ich2Ggrate = 0;
                                    byte[] db = new byte[12];
                                    Marshal.Copy((IntPtr)((int)d_image.Scan0 + (int)rFPDest + 3), db, 0, 12);
                                    db[11] = Convert.ToByte((Convert.ToInt32(db[11]) + Convert.ToInt32(db[8])) / 2);
                                    db[10] = Convert.ToByte((Convert.ToInt32(db[10]) + Convert.ToInt32(db[7])) / 2);
                                    db[9] = Convert.ToByte((Convert.ToInt32(db[9]) + Convert.ToInt32(db[6])) / 2);
                                    db[2] = Convert.ToByte((Convert.ToInt32(db[2]) + Convert.ToInt32(db[5])) / 2);
                                    db[2] = Convert.ToByte((Convert.ToInt32(db[1]) + Convert.ToInt32(db[4])) / 2);
                                    db[0] = Convert.ToByte((Convert.ToInt32(db[0]) + Convert.ToInt32(db[3])) / 2);

                                    //' Split color changes between pixels that we need to write. So we can create a gradient effect
                                    ich2Rgrate = (Convert.ToInt32(db[2]) - Convert.ToInt32(db[11])) / (sfp + 1);
                                    ich2Ggrate = (Convert.ToInt32(db[1]) - Convert.ToInt32(db[10])) / (sfp + 1);
                                    ich2Bgrate = (Convert.ToInt32(db[0]) - Convert.ToInt32(db[9])) / (sfp + 1);

                                    //' Apply Smoothing
                                    for (int i = 0; i <= sfp - 1; i++)
                                    {
                                        //' CH2 Smoothing
                                        if ((!b_SwapRL))
                                        {
                                            //' BLUE
                                            Marshal.WriteByte((IntPtr)((int)d_anag.Scan0 + (int)rFPDest + (-i * 3)), (byte)(db[9] + ((sfp - i) * ich2Bgrate)));
                                            Marshal.WriteByte((IntPtr)(int)d_anag.Scan0 + (int)rFPDest + (-i * 3) + 1, (byte)(db[10] + ((sfp - i) * ich2Ggrate)));
                                        }
                                        else
                                        {
                                            //' RED
                                            Marshal.WriteByte((IntPtr)((int)d_anag.Scan0 + (int)rFPDest + (-i * 3) + 2), (byte)(db[11] + ((sfp - i) * ich2Rgrate)));
                                        }
                                    }
                                }
                                //' Go to Next Pixel
                                rFPDest += 3;
                            }
                        }

                        //' Closing direct access
                        DepthMap.UnlockBits(d_depth);
                        Image.UnlockBits(d_image);
                        b_Anaglyph.UnlockBits(d_anag);
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        /// <summary>
        /// Generate Stereoscopic
        /// </summary>
        /// <param name="Image"></param>
        /// <param name="DepthMap"></param>
        /// <returns></returns>
        public static bool GenerateStereoscopic(Bitmap Image, Bitmap DepthMap)
        {
            //' Checking if image and depthmap have same size
            if (Image.Width != DepthMap.Width || Image.Height != DepthMap.Height)
                throw new ArgumentException("Size of Image and DepthMap are not same.");
            //' Check if image and depthmap are 24bitRGB or not
            if (Image.PixelFormat != PixelFormat.Format24bppRgb || Image.PixelFormat != PixelFormat.Format24bppRgb)
                throw new ArgumentException("Image and/or DepthMap are/is not 24bitRGB");
            try
            {
                //' Locking image and depthmap do other threads cant access them when we work on them
                lock (Image)
                {
                    lock (DepthMap)
                    {
                        //' Create CH2 bitmap for saving output
                        b_CH2 = new Bitmap(DepthMap.Width, DepthMap.Height);
                        //' Create a rect object, Same size as CH2 bitmap. Need for direct access in memory
                        Rectangle r_CH2 = new Rectangle(0, 0, DepthMap.Width, DepthMap.Height);
                        //' Create CH1 bitmap for saving output
                        b_CH1 = new Bitmap(DepthMap.Width, DepthMap.Height);
                        //' Create a rect object, Same size as CH1 bitmap. Need for direct access in memory
                        Rectangle r_CH1 = new Rectangle(0, 0, DepthMap.Width, DepthMap.Height);
                        //' Calculating real width of image (By byte)
                        int i_width = DepthMap.Width * 3;
                        if (i_width % 4 != 0)
                        {
                            i_width = 4 * (i_width / 4 + 1);
                        }

                        //' How much we need to move each pixel per depth byte
                        double hsrate = i_maxDisplacement / 255;

                        //' Creating a rect object with same size. For Depth map
                        Rectangle r_depth = new Rectangle(0, 0, DepthMap.Width, DepthMap.Height);
                        //' Opening direct access to bitmap data in memory for Depth map
                        BitmapData d_depth = DepthMap.LockBits(r_depth, ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

                        //' Creating a rect object with same size. For Image
                        Rectangle r_image = new Rectangle(0, 0, Image.Width, Image.Height);
                        //' Opening direct access to bitmap data in memory for Image
                        BitmapData d_image = Image.LockBits(r_image, ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

                        //' Opening direct access to bitmap data in memory for CH2
                        BitmapData d_ch2 = b_CH2.LockBits(r_CH2, ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                        //' Opening direct access to bitmap data in memory for CH1
                        BitmapData d_ch1 = b_CH1.LockBits(r_CH1, ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

                        int sfp = 0;
                        for (int y = 0; y <= DepthMap.Height - 1; y++)
                        {
                            //' Calculate location of current line's last free pixel
                            IntPtr rLPDest = (IntPtr)((y + 1) * i_width - (i_maxDisplacement * 3) - 3);

                            //' Calculate location of current line's first free pixel
                            IntPtr rFPDest = (IntPtr)(y * i_width + (i_maxDisplacement * 3));

                            //' Count for each pixel on width of image. Cut MaxDisplacementfrom both sides

                            for (int x = i_maxDisplacement; x <= DepthMap.Width - 1 - i_maxDisplacement; x++)
                            {
                                ///''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Right 2 Left  <<--
                                //' Read Depth, Right to Left
                                byte depthrgb = Marshal.ReadByte((IntPtr)((int)d_depth.Scan0 + (int)rLPDest + 1));
                                if (InverseDepthMap)
                                    depthrgb = (byte)(255 - depthrgb);

                                //' Calculate displacement offset, Right to Left
                                sfp = (int)(depthrgb * hsrate);

                                //' Read a pixel from image, Right to Left
                                byte[] imagergb = new byte[3];
                                Marshal.Copy((IntPtr)((int)d_image.Scan0 + (int)rLPDest), imagergb, 0, 3);

                                //' Correct CH2 Displacement, Right to Left
                                Marshal.Copy(imagergb, 0, (IntPtr)((int)d_ch1.Scan0 + (int)rLPDest + ((sfp) * 3)), 3);

                                //' Smoothing
                                if (b_Smoothing & sfp != 0)
                                {
                                    //' Calculate color changes between pixels (For better smoothing we use 4 pixel and then get an average)
                                    double ich2Rgrate = 0;
                                    double ich2Ggrate = 0;
                                    double ich2Bgrate = 0;
                                    byte[] db = new byte[12];
                                    Marshal.Copy((IntPtr)((int)d_image.Scan0 + (int)rLPDest - 12), db, 0, 12);
                                    db[11] = Convert.ToByte((Convert.ToInt32(db[11]) + Convert.ToInt32(db[8])) / 2);
                                    db[10] = Convert.ToByte((Convert.ToInt32(db[10]) + Convert.ToInt32(db[7])) / 2);
                                    db[9] = Convert.ToByte((Convert.ToInt32(db[9]) + Convert.ToInt32(db[6])) / 2);
                                    db[2] = Convert.ToByte((Convert.ToInt32(db[2]) + Convert.ToInt32(db[5])) / 2);
                                    db[1] = Convert.ToByte((Convert.ToInt32(db[1]) + Convert.ToInt32(db[4])) / 2);
                                    db[0] = Convert.ToByte((Convert.ToInt32(db[0]) + Convert.ToInt32(db[3])) / 2);

                                    //' Split color changes between pixels that we need to write. So we can create a gradient effect
                                    ich2Rgrate = (Convert.ToInt32(db[2]) - Convert.ToInt32(db[11])) / (sfp + 1);
                                    ich2Ggrate = (Convert.ToInt32(db[1]) - Convert.ToInt32(db[10])) / (sfp + 1);
                                    ich2Bgrate = (Convert.ToInt32(db[0]) - Convert.ToInt32(db[9])) / (sfp + 1);

                                    //' Apply Smoothing
                                    for (int i = 0; i <= sfp - 1; i++)
                                    {
                                        //' CH2 Smoothing
                                        db[0] = (byte)(db[9] + (i * ich2Bgrate));
                                        db[1] = (byte)(db[10] + (i * ich2Ggrate));
                                        db[2] = (byte)(db[11] + (i * ich2Rgrate));
                                        Marshal.Copy(db, 0, (IntPtr)((int)d_ch1.Scan0 + (int)rLPDest + (((sfp - 1) - i) * 3)), 3);
                                    }
                                }
                                //' Go to Last Pixel
                                rLPDest -= 3;

                                ///''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Left 2 Right  -->>
                                //' Read Depth, Left to Right
                                depthrgb = Marshal.ReadByte((IntPtr)((int)d_depth.Scan0 + (int)rFPDest + 1));
                                if (InverseDepthMap)
                                    depthrgb = (byte)(255 - depthrgb);

                                //' Calculate displacement offset, Left to Right
                                sfp = (int)(depthrgb * hsrate);

                                //' Read a pixel from image, Left to Right
                                Marshal.Copy((IntPtr)((int)d_image.Scan0 + (int)rFPDest), imagergb, 0, 3);

                                //' Correct CH1 Displacement, Left to Right
                                Marshal.Copy(imagergb, 0, (IntPtr)((int)d_ch2.Scan0 + (int)rFPDest + (-sfp * 3)), 3);

                                //' Smoothing
                                if (b_Smoothing & sfp != 0)
                                {
                                    //' Calculate color changes between pixels (For better smoothing we use 4 pixel and then get an average)
                                    double ich1Rgrate = 0;
                                    double ich1Ggrate = 0;
                                    double ich1Bgrate = 0;
                                    byte[] db = new byte[12];
                                    Marshal.Copy((IntPtr)((int)d_image.Scan0 + (int)rFPDest + 3), db, 0, 12);
                                    db[11] = Convert.ToByte((Convert.ToInt32(db[11]) + Convert.ToInt32(db[8])) / 2);
                                    db[10] = Convert.ToByte((Convert.ToInt32(db[10]) + Convert.ToInt32(db[7])) / 2);
                                    db[9] = Convert.ToByte((Convert.ToInt32(db[9]) + Convert.ToInt32(db[6])) / 2);
                                    db[2] = Convert.ToByte((Convert.ToInt32(db[2]) + Convert.ToInt32(db[5])) / 2);
                                    db[1] = Convert.ToByte((Convert.ToInt32(db[1]) + Convert.ToInt32(db[4])) / 2);
                                    db[0] = Convert.ToByte((Convert.ToInt32(db[0]) + Convert.ToInt32(db[3])) / 2);

                                    //' Split color changes between pixels that we need to write. So we can create a gradient effect
                                    ich1Rgrate = (Convert.ToInt32(db[2]) - Convert.ToInt32(db[11])) / (sfp + 1);
                                    ich1Ggrate = (Convert.ToInt32(db[1]) - Convert.ToInt32(db[10])) / (sfp + 1);
                                    ich1Bgrate = (Convert.ToInt32(db[0]) - Convert.ToInt32(db[9])) / (sfp + 1);

                                    //' Apply Smoothing
                                    for (int i = 0; i <= sfp - 1; i++)
                                    {
                                        //' CH1 Smoothing
                                        db[0] = (byte)(db[9] + ((sfp - i) * ich1Bgrate));
                                        db[1] = (byte)(db[10] + ((sfp - i) * ich1Ggrate));
                                        db[2] = (byte)(db[11] + ((sfp - i) * ich1Rgrate));
                                        Marshal.Copy(db, 0, (IntPtr)((int)d_ch2.Scan0 + (int)rFPDest + (-i * 3)), 3);
                                    }
                                }
                                //' Go to Next Pixel
                                rFPDest += 3;
                            }
                        }

                        //' Closing direct access
                        DepthMap.UnlockBits(d_depth);
                        Image.UnlockBits(d_image);
                        b_CH2.UnlockBits(d_ch2);
                        b_CH1.UnlockBits(d_ch1);
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        /// <summary>
        /// Gets or sets inverse Depth map Mode
        /// </summary>
        public static bool InverseDepthMap
        {
            get { return b_InverseDepthMap; }
            set { b_InverseDepthMap = value; }
        }

        /// <summary>
        /// clones this instance
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new StereoFromStillAndDepthmap(this);
        }

        /// <summary>
        /// Process
        /// </summary>
        /// <param name="_bitmap1"></param>
        /// <param name="_bitmap2"></param>
        /// <returns></returns>
        public UnsafeBitmap Process(UnsafeBitmap _bitmap1, UnsafeBitmap _bitmap2)
        {
            _bitmap1.UnlockImage();
            _bitmap2.UnlockImage();
            GenerateAnaglyph(_bitmap1.InternalBitmap, _bitmap2.InternalBitmap);
            //GenerateStereoscopic(_bitmap1.InternalBitmap, _bitmap2.InternalBitmap);
            return b_Anaglyph;
        }
    }
}
